import Vue from 'vue'

import Cookies from 'js-cookie'

import Element from 'element-ui'
import './assets/styles/element-variables.scss'

import '@/assets/styles/index.scss' // global css
import '@/assets/styles/ruoyi.scss' // ruoyi css
import App from './App'
import store from './store'
import router from './router'
import directive from './directive' // directive
import plugins from './plugins' // plugins
import { download } from '@/utils/request'

import './assets/icons' // icon
import './permission' // permission control
import { getDicts } from "@/api/system/dict/data";
import { getConfigKey } from "@/api/system/config";
import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi";
// 分页组件
import Pagination from "@/components/Pagination";
// 自定义表格工具组件
import RightToolbar from "@/components/RightToolbar"
// 富文本组件
import Editor from "@/components/Editor"
// 文件上传组件
import FileUpload from "@/components/FileUpload"
// 图片上传组件
import ImageUpload from "@/components/ImageUpload"
// 图片预览组件
import ImagePreview from "@/components/ImagePreview"
// 字典标签组件
import DictTag from '@/components/DictTag'
// 头部标签组件
import VueMeta from 'vue-meta'
// 字典数据组件
import DictData from '@/components/DictData'
import MessageDialog from '@/components/MessageDialog'

// 全局方法挂载
Vue.prototype.getDicts = getDicts
Vue.prototype.getConfigKey = getConfigKey
Vue.prototype.parseTime = parseTime
Vue.prototype.resetForm = resetForm
Vue.prototype.addDateRange = addDateRange
Vue.prototype.selectDictLabel = selectDictLabel
Vue.prototype.selectDictLabels = selectDictLabels
Vue.prototype.download = download
Vue.prototype.handleTree = handleTree

// 全局组件挂载
Vue.component('DictTag', DictTag)
Vue.component('Pagination', Pagination)
Vue.component('RightToolbar', RightToolbar)
Vue.component('Editor', Editor)
Vue.component('FileUpload', FileUpload)
Vue.component('ImageUpload', ImageUpload)
Vue.component('ImagePreview', ImagePreview)

Vue.use(directive)
Vue.use(plugins)
Vue.use(VueMeta)
DictData.install()

// 创建WebSocket连接
let ws = null;
let reconnectAttempts = 0;
const maxReconnectAttempts = 5;
const reconnectInterval = 3000; // 3秒
let heartbeatTimer = null;

// 创建消息弹窗实例
const MessageDialogConstructor = Vue.extend(MessageDialog)
const messageDialog = new MessageDialogConstructor().$mount()
document.body.appendChild(messageDialog.$el)

// 获取Cookie的函数
function getCookie(name) {
  const value = `; ${document.cookie}`;
  const parts = value.split(`; ${name}=`);
  if (parts.length === 2) return parts.pop().split(';').shift();
  return null;
}

// 创建WebSocket连接的函数
export function createWebSocket() {
  // 从Cookie中获取token
  const token = getCookie('Admin-Token');
  if (!token) {
    console.error('未找到token，无法建立WebSocket连接');
    return;
  }

  // 如果已经存在连接且状态正常，不重复连接
  if (ws && ws.readyState === WebSocket.OPEN) {
    console.log('WebSocket已连接，跳过创建');
    return;
  }

  // 如果已经存在连接，先关闭
  if (ws) {
    ws.close();
    ws = null;
  }

  // 清除之前的心跳定时器
  if (heartbeatTimer) {
    clearInterval(heartbeatTimer);
    heartbeatTimer = null;
  }

  try {
    // 创建WebSocket连接，通过URL参数传递token
    const wsUrl = `ws://47.110.138.104:8080/jkgl/userConn?Authorization=${encodeURIComponent(token)}`;
    ws = new WebSocket(wsUrl);

    // 在连接建立后设置事件处理器
    ws.onopen = () => {
      console.log('WebSocket连接已打开');
      reconnectAttempts = 0; // 重置重连次数

      // 清空本地存储的消息
      localStorage.removeItem('messages');

      // 设置心跳检测
      heartbeatTimer = setInterval(() => {
        if (ws && ws.readyState === WebSocket.OPEN) {
          // 连接正常，只发送心跳包
          ws.send('ping');
        } else if (ws && ws.readyState === WebSocket.CLOSED) {
          // 连接已关闭，触发重连
          console.log('心跳检测发现连接已关闭，触发重连');
          clearInterval(heartbeatTimer);
          heartbeatTimer = null;
          createWebSocket();
        }
      }, 30000); // 每30秒发送一次心跳

      // 确保 App 组件实例已经挂载
      setTimeout(() => {
        const app = document.querySelector('#app').__vue__;
        if (!app) {
          console.error('App组件实例未找到');
        }
      }, 1000);
    };

    ws.onmessage = (event) => {
      console.log('收到消息:', event.data);
      try {
        // 解析JSON消息
        const message = JSON.parse(event.data);
        // 如果消息包含title和context，添加到消息列表
        if (message.title && message.context) {
          // 获取App组件实例
          const app = document.querySelector('#app').__vue__;
          if (app && app.addMessage) {
            // 获取当前存储的消息
            const savedMessages = localStorage.getItem('messages');
            let messages = savedMessages ? JSON.parse(savedMessages) : [];

            // 添加新消息
            const newMessage = {
              title: message.title,
              context: message.context,
              time: new Date().toLocaleString(),
              read: false
            };

            // 将新消息添加到数组开头
            messages.unshift(newMessage);

            // 更新本地存储
            localStorage.setItem('messages', JSON.stringify(messages));

            // 更新组件中的消息列表
            app.messages = messages;
            app.hasNewMessage = true;
          } else {
            // 如果App组件实例未找到，将消息存储到临时变量
            if (!window.pendingMessages) {
              window.pendingMessages = [];
            }
            window.pendingMessages.push(message);
            console.log('消息已存储到待处理队列');
          }
        }
      } catch (error) {
        console.error('解析WebSocket消息失败:', error);
      }
    };

    ws.onerror = (error) => {
      console.error('WebSocket错误:', error);
      // 发生错误时，等待连接关闭事件处理重连
    };

    ws.onclose = () => {
      console.log('WebSocket连接已关闭');
      // 清除心跳定时器
      if (heartbeatTimer) {
        clearInterval(heartbeatTimer);
        heartbeatTimer = null;
      }

      // 尝试重连
      if (reconnectAttempts < maxReconnectAttempts) {
        reconnectAttempts++;
        console.log(`尝试第 ${reconnectAttempts} 次重连...`);
        setTimeout(createWebSocket, reconnectInterval);
      } else {
        console.log('达到最大重连次数，停止重连');
      }
    };

    // 将WebSocket实例挂载到Vue原型上，以便在组件中使用
    Vue.prototype.$ws = ws;

  } catch (error) {
    console.error('创建WebSocket连接失败:', error);
    // 发生错误时尝试重连
    setTimeout(createWebSocket, reconnectInterval);
  }
}

// 导出检查连接状态的函数
export function ensureWebSocketConnection() {
  if (!ws || ws.readyState !== WebSocket.OPEN) {
    createWebSocket();
    return false;
  }
  return true;
}

/**
 * If you don't want to use mock-server
 * you want to use MockJs for mock api
 * you can execute: mockXHR()
 *
 * Currently MockJs will be used in the production environment,
 * please remove it before going online! ! !
 */

Vue.use(Element, {
  size: Cookies.get('size') || 'medium' // set element-ui default size
})

Vue.config.productionTip = false

// 在创建Vue实例前检查token并建立WebSocket连接
const token = getCookie('Admin-Token');
if (token) {
  console.log('检测到已登录状态，尝试建立WebSocket连接');
  createWebSocket();
}

new Vue({
  el: '#app',
  router,
  store,
  render: h => h(App)
})
